home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Documentation / Tech Notes & Articles / Recipes / Part Persistency / Part Init & Externalizing < prev    next >
Encoding:
Text File  |  1995-07-11  |  5.0 KB  |  175 lines  |  [TEXT/ttxt]

  1. OpenDoc™ Recipes
  2.  
  3.  
  4. Part Init & Externalizing recipe
  5. By The OpenDoc Design Team
  6. July 11th, 1995
  7.  
  8.  
  9. © 1993-1995  Apple Computer, Inc. All Rights Reserved.
  10. Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
  11. Mac and OpenDoc are trademarks of Apple Computer, Inc. 
  12.  
  13.  
  14. Introduction
  15.  
  16. This document contains some sample code showing how a Part Editor externalizes and internalizes itself. 
  17.  
  18. The sample code shown here is for a very simple Part Editor. Its assumptions may not be valid for a Part Editor with more functionality:
  19.  
  20. •fPartData is a Pascal string (Str255) which holds the Part Content or Part Data.
  21. •The sample code reads and writes the entire Part Data from and to persistent storage.
  22. •The sample code uses a fDirty flag which it sets to true when its contents change.
  23. •The sample code uses a fSelf field to hang onto the partwrapper object.
  24.  
  25. Proper treatment of permissions
  26.  
  27. •Note that the part is responsible for caching the draft permissions in InitPartFromStorage.  The sample code does this by assigning a field 
  28. fPermissions = storageUnit->GetDraft(ev)->GetPermissions(ev);
  29. in the  InitPartFromStorage.  Whenever the potential for changing user content exists, the part should check to make sure
  30. fPermissions >= kDPSharedWrite
  31. before changing any of the content.  Also, as a side effect, if fPermissions < kDPSharedWrite then fDirty should never be able to become kODTrue, and as a result, the Externalize method will never write to the contents property.
  32.  
  33.  
  34. PartWrapper
  35.  
  36. In addition to a Storage Unit, InitPart and InitPartFromStorage methods on ODPart also takes an extra parameter partWrapper.   The partWrapper parameter represents a delegator object which OpenDoc uses to insulate the rest of OpenDoc from having to have a direct pointer to your ODPart object.  This feature helps implement features such as being able to change the editor of part without closing and reopening the document.  Plus, it makes an excellent bottleneck for platform developers.  For the most part, all the partWrapper does is delegate methods of the part API to your ODPart object.
  37.  
  38. The Part Editor must save this parameter in the Part's internal field; you'll see this in the sample code below. Whenever an OpenDoc API requires the Part Editor to pass in an ODPart* representing the Part, instead of passing in somSelf, the Part Editor MUST pass in partWrapper stored in the Part's internal field.  An example is when registering the Part for idle time.  A Part Editor should NEVER pass somSelf in as a parameter to an OpenDoc API call.
  39.  
  40. Sample Code for Initialization
  41.  
  42. // includes the appropriate .xh files from OpenDoc
  43.  
  44. #include "StorageU.xh"
  45.  
  46. #include "StdProps.xh"
  47.  
  48. #include "POUtils.h"
  49.  
  50.  
  51.  
  52. // Define the Part Kind.
  53. //
  54. // This should probably be in your part's …def.h file which should be #included 
  55. // in your .r file for your 'nmap' resources
  56.  
  57. #define kMyPartKind    "Sample:Kind:CMyKind"
  58.  
  59. ...
  60. void    MyPartInitPart(MyPart* somSelf, 
  61.                                     Enviornment* ev,
  62.                                     ODStorageUnit* storageUnit,
  63.                                     ODPart* partWrapper)
  64. {
  65.  
  66.     ...
  67.  
  68.     // Call your parent's init routine
  69.  
  70.     parent_InitPart(somSelf, ev, storageUnit, partWrapper);
  71.  
  72.  // set your dirty flag
  73.  
  74.  fDirty = kODTrue;
  75.  
  76.     // save off the partwrapper object
  77.  
  78.     fSelf = partWrapper;
  79.  
  80. }
  81.  
  82. void    MyPartInitPartFromStorage(MyPart* somSelf,
  83.                                     Environment* ev,
  84.                                     ODStorageUnit* storageUnit,
  85.                                     ODPartWrapper* partWrapper)
  86.  
  87. {
  88.  
  89.     // Initialize the parent.
  90.  
  91.     parent_InitPartFromStorage(somSelf, ev, storageUnit, partWrapper);
  92.  
  93.     // Focus to the value where the Part Data is stored.
  94.  
  95.     storageUnit->Focus(ev,
  96.                         kODPropContents,
  97.                         kODPosUndefined,
  98.                         kMyPartKind,
  99.                         0,
  100.                         kODPosUndefined);
  101.  
  102.     // Get the size of the string.
  103.  
  104.     fPartData[0] = storageUnit->GetSize(ev);
  105.  
  106.     // Get the string itself
  107.  
  108.     storageUnit->GetValue(fPartData[0],&(fPartData[1]));
  109.  
  110.     // save off the partwrapper object
  111.  
  112.     fSelf = partWrapper;
  113.  
  114.     // Note the draft permissions, in order to avoid writing to a readonly draft.
  115.  
  116.     fPermissions = storageUnit->GetDraft(ev)->GetPermissions(ev);
  117.  
  118.     // Set the dirty flag to false.
  119.  
  120.     fDirty = kODFalse;
  121.  
  122. }
  123.  
  124. Sample Code for Externalization
  125.  
  126. void    MyPartExternalize(MyPart* somSelf,
  127.                                 Environment* ev)
  128.  
  129. {
  130.  
  131.     // Only Externalize when the Part has been updated.
  132.  
  133.     // Externalize the parent.
  134.  
  135.     parent_Externalize(somSelf, ev);
  136.  
  137.     if (fDirty) {
  138.  
  139.         // Get the Part's Storage Unit.
  140.  
  141.         ODStorageUnit* storageUnit = somSelf->GetStorageUnit(ev);
  142.  
  143.   if (storageUnit->Exists(ev, kODPropContents, kMyPartKind, 0))
  144.         {
  145.         // Focus to the desired value.
  146.  
  147.         storageUnit->Focus(ev,
  148.                                 kODPropContents,
  149.                                 kODPosUndefined,
  150.                                 kMyPartKind,
  151.                                 0,
  152.                                 kODPosUndefined);
  153.         }
  154.         else
  155.         {
  156.             storageUnit->AddProperty(ev, kODPropContents);
  157.             storageUnit->AddValue(ev, kMyPartKind);
  158.  
  159.             // Adding a property and value has the sideeffect of focusing the storageunit to that value.
  160.         }
  161.  
  162.         // Write out the Part Data
  163.  
  164.         storageUnit->SetValue(ev, fPartData[0],&(fPartData[1]));
  165.     
  166.         // Set the dirty flag to kODFalse to signify that the Part is clean.
  167.  
  168.         fDirty = kODFalse;
  169.  
  170.     }
  171.  
  172. }
  173.  
  174.